home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS22.ADF
/
Garden
/
Garden.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-06-30
|
11KB
|
367 lines
/*************************************************************************
/* Garden.c - An "electronic wallpaper" amusement based on finite-state **
** automata **
** ⌐ 1987, Kevin A. Bjorke **
** National Pixel Products, Valencia, CA 91355 **
** Nov 84, Nov 85, March 86, May 87 **
*************************************************************************/
/*************************************************
** Compile under Lattice 3.10 like so: **
** lc -b -r -v -qram: -M Garden **
** blink with Garden.With **
** Where file Garden.With contains: **
** FROM lib:c.o sys:Garden.o **
** TO sys:Garden **
** LIB lib:amiga.lib lib:lc.lib **
** MAP ram:Garden.map **
** VERBOSE **
** PLAIN **
** SMALLCODE **
** SMALLDATA **
** NODEBUG **
*************************************************/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <intuition/intuition.h>
#include <graphics/text.h>
#define SPAN 320 /* Number of Cell units */
#define EMPTY 0 /* No cell here (in tube[][]) */
#define CELL 1 /* Cell here */
#define MINLINE 1 /* top (vertical) scanline */
#define MAXLINE 200 /* bottom scanline */
#define SpanClip(a) ((a)<0)?(SPAN+(a)):(((a)>=SPAN)?((a)-SPAN):(a))
#define SpanClip2(a) ((a)>=SPAN)?((a)-SPAN):(a)
/****************************************************************/
/****** Misc Externs & IntuiStuff *******************************/
/****************************************************************/
extern long GfxBase;
extern long IntuitionBase;
extern struct InputEvent *Intuition();
extern struct Window *OpenWindow();
extern struct Screen *OpenScreen();
/****************/
extern VOID AmiSetup(); /* forward declarations of functions below */
extern VOID AmiCleanup();
extern VOID Grow();
extern VOID CellSetup();
extern VOID DrawOld();
extern UWORD Age();
extern SHORT Event();
/****************************************************************/
/********* IntuiJunk ********************************************/
/****************************************************************/
struct TextAttr ROMFont8 = {
"topaz.font",8,0,0
};
USHORT class = NULL;
USHORT code;
struct Window *wn = NULL;
struct Screen *sc = NULL;
struct RastPort *rp;
struct ViewPort *vp;
struct IntuiMessage *message;
/****************************************************************/
/****************************************************************/
/****************************************************************/
struct IntuiText MenText[3] = {
{19,1,JAM1,0,0,&ROMFont8,"About",NULL},
{17,1,JAM1,0,0,&ROMFont8,"Clear",NULL},
{15,1,JAM1,0,0,&ROMFont8,"Quit", NULL}
};
struct MenuItem Quits = {
NULL, 0,18, 50,9, ITEMTEXT|ITEMENABLED|HIGHCOMP,
0L,(APTR)&MenText[2], NULL,'\0',NULL,0
};
struct MenuItem Clear = {
&Quits, 0,9, 50,9, ITEMTEXT|ITEMENABLED|HIGHCOMP,
0L,(APTR)&MenText[1], NULL,'\0',NULL,0
};
struct MenuItem About = {
&Clear, 0,0, 50,9, ITEMTEXT|ITEMENABLED|HIGHCOMP,
0L,(APTR)&MenText[0], NULL,'\0',NULL,0
};
struct Menu Garden = {
NULL, 0,0, (7<<3),9,MENUENABLED|MIDRAWN,
"Garden",&About
};
struct IntuiText ReqText[7] = {
{15,1,JAM2,10, 8,&ROMFont8,"GARDEN by Kevin Bjorke",&ReqText[1]},
{ 6,1,JAM2,10,16,&ROMFont8,"⌐ 1987, National Pixel",&ReqText[2]},
{19,1,JAM2,18,24,&ROMFont8,"CIS:74756,464", &ReqText[3]},
{31,1,JAM2,18,32,&ROMFont8,"PLink:OJS637", &ReqText[4]},
{17,1,JAM2,18,40,&ROMFont8,"BIX:kbjorke", NULL},
{13,1,JAM2,AUTOLEFTEDGE,AUTOTOPEDGE,&ROMFont8,"Okay",NULL},
{13,1,JAM2,AUTOLEFTEDGE,AUTOTOPEDGE,&ROMFont8,"Fine",NULL}
};
UWORD GardenCMap[32] = { /* Colors */
0x22D,0xFC2,0x9C0,0x4A0,0x360,0x7C0,0xA4A,0x4A0,
0x380,0x190,0x0A0,0x2B8,0x4AD,0x77E,0x2C4,0xB05,
0x5B0,0xB72,0x933,0x080,0xFFE,0x183,0x2C6,0x9D0,
0x777,0x4A0,0xD92,0xA4A,0xEE0,0x7C0,0xF83,0x77E
};
/****************************************************************/
/****** Screen **************************************************/
/****************************************************************/
struct NewScreen ns = {
0,0, /* start pos.*/
320,200,5, /* width height depth (2 bit planes) */
3,0, /* detail pen, block pen */
0, /* ViewModes */
CUSTOMSCREEN, /* Type */
&ROMFont8, /* Font */
NULL, /* Title */
NULL, NULL /* Gadgets, CustomBitMap */
};
/****************************************************************/
/******** Window ************************************************/
/****************************************************************/
struct NewWindow nw = {
0,0,320,200,
12,0, /* detail, block pens */
MENUPICK, /* IDCMPFlags */
BACKDROP|BORDERLESS|SMART_REFRESH|ACTIVATE, /* Flags */
NULL, /* FirstGadget */
NULL, /* CheckMark */
NULL, /* Title */
NULL, /* Screen */
NULL, /* CustomBitMap */
0,0,0,0, /* sizing limits */
CUSTOMSCREEN
};
/****************************************************************/
/******* Gardening Variables ************************************/
/****************************************************************/
UBYTE tube[2][SPAN]; /* cell reproduction happens here */
UWORD new = 0;
UWORD old = 1;
SHORT CellColr = 0;
SHORT ScanLine = -1;
/****************************************************************/
/***** Execution Begins *****************************************/
/****************************************************************/
VOID _main()
{
ULONG Seconds, Micros;
AmiSetup();
CurrentTime(&Seconds,&Micros);
srand((unsigned)(Micros & 0xFFFF));
do {
if (ScanLine<MINLINE)
CellSetup();
else
Grow();
if(wn->UserPort->mp_SigBit) {
message = (struct IntuiMessage *)GetMsg(wn->UserPort);
if(message != NULL) {
class = message->Class;
code = message->Code;
ReplyMsg(message);
}
}
} while(Event());
AmiCleanup();
}
/****************************************************************/
/****** IDCMP Filtering *****************************************/
/****************************************************************/
SHORT Event()
{
register UWORD u;
SHORT MNum, INum;
if (class == MENUPICK) {
class = NULL;
MNum = MENUNUM(code);
INum = ITEMNUM(code);
if ((MNum == 0)&&(INum == 2)) {
return(NULL); /* byebye */
}
if ((MNum == 0)&&(INum == 1)) {
/* SetRast(rp,0); */
for (u=0;u<200;u+=4) {
ScrollRaster(rp,0,-4,0,0,320,200);
WaitTOF();
}
ScanLine = -1;
return(2);
}
if ((MNum == 0)&&(INum == 0)) {
AutoRequest(wn,&ReqText[0],&ReqText[5],&ReqText[6],
NULL,NULL,(36+(22<<3)),85);
return(3);
}
}
class = NULL;
return(-1);
}
/****************************************************************/
/***** Main Action **********************************************/
/****************************************************************/
VOID Grow()
{
DrawOld();
if (Age() > 0) {
old = new;
new ^= 1;
--ScanLine;
} else {
ScanLine = -1; /* force a CellSetup() */
}
}
/****************************************************************/
/****** Display Most-recent layer *******************************/
/****************************************************************/
VOID DrawOld()
{
UWORD CellCt;
Move(rp,0,ScanLine);
for (CellCt = 0; CellCt < SPAN; ++CellCt) {
if (tube[old][CellCt] == CELL)
WritePixel(rp,CellCt,ScanLine);
}
}
/****************************************************************/
/***** Make a Random Cell Line **********************************/
/****************************************************************/
VOID CellSetup()
{
register UWORD CellCt, j;
old = 0;
new = 1;
for (CellCt = 0; CellCt < SPAN; ++CellCt) {
if ((CellCt & 15) == 0)
j = rand();
tube[old][CellCt] = (j & 1);
j >>= 1;
}
CellColr = ++CellColr & 31;
SetAPen(rp,CellColr);
ScanLine = (MAXLINE-1);
}
/****************************************************************/
/***** Generate New Cells ***************************************/
/****************************************************************/
/*****************************************************************
** Algorithm Notes: **
** This algorithm is extremely simple, and has little basis in **
** real growth mechanisms, except perhaps those of lakeside **
** algae. Instead, it's more akin to Conway's LIFE, but is only **
** one-dimensional -- by saving the history as successive scan- **
** lines, we get plantlike growths. The algorithm is this: scan **
** the local pixel and its four closest neighbors. If the the **
** sum is 2 or 4, live. If not, die. Simple, eh? **
*****************************************************************/
UWORD Age()
{
register UWORD nCells = 0;
register UWORD where;
register SHORT trail, nPals, CellCt;
nPals = tube[old][SPAN-3] + tube[old][SPAN-2] + tube[old][SPAN-1] +
tube[old][0] + tube[old][1]; /* Solve LAST cell first */
for(CellCt=0; CellCt<SPAN; ++CellCt) {
trail = SpanClip(CellCt-3); /* solve incrementally */
where = SpanClip2(CellCt+2); /* never negative */
nPals += (tube[old][where]-tube[old][trail]);
if ((nPals==2)||(nPals==4)) {
tube[new][CellCt] = CELL;
++nCells;
} else {
tube[new][CellCt] = EMPTY;
}
}
return(nCells);
}
/****************************************************************/
/******* Setup Screen *******************************************/
/****************************************************************/
VOID AmiSetup()
{
if ((GfxBase = OpenLibrary("graphics.library",LIBRARY_VERSION)) == NULL)
Exit(1);
if ((IntuitionBase = OpenLibrary("intuition.library",LIBRARY_VERSION)) ==
NULL) {
AmiCleanup();
Exit(1);
}
if ((sc = OpenScreen(&ns)) == NULL) {
AmiCleanup();
Exit(0);
}
nw.Screen = sc;
if ((wn = OpenWindow(&nw)) == NULL) {
AmiCleanup();
Exit(2);
}
rp = wn->RPort;
vp = &wn->WScreen->ViewPort;
LoadRGB4(vp,GardenCMap,32);
ShowTitle(sc,FALSE);
SetAPen(rp,1);
SetDrMd(rp,JAM1);
SetMenuStrip(wn,&Garden);
}
/****************************************************************/
/****************************************************************/
/****************************************************************/
VOID AmiCleanup()
{
if (wn != NULL) {
ClearMenuStrip(wn);
CloseWindow(wn);
}
if (sc != NULL)
CloseScreen(sc);
if (GfxBase != NULL)
CloseLibrary(GfxBase);
if (IntuitionBase != NULL)
CloseLibrary(IntuitionBase);
}
/****************************************************************/
/******************************************************** eof ***/
/****************************************************************/